import feedparser

class CommandParser(object):
    commands = ['sub', 'unsub', 'ls', 'pause', 'resume', 'grep']
    _subscripted = {}
    _user, _cmd, _feed_url, _keyword = '', '', '', []

    def __init__(self, user, cmd = 'ls', feed_url = '', keyword = []):
        if cmd.lower() not in self.commands:
            raise CommandError 
        self._user = user
        self._cmd = cmd
        self._feed_url = feed_url
        self._keyword = keyword

    def parser(self):
        if self._cmd == 'sub':
            return self.sub()
        if self._cmd == 'unsub':
            return self.unsub()
        if self._cmd == 'ls':
            return self.ls()
        if self._cmd == 'pause':
            return self.pause()
        if self._cmd == 'resume':
            return self.resume()
        if self._cmd == 'grep':
            return self.grep()
        
        return self.ls()

    def sub(self):
        if not self._feed_url:
            return self.usage('sub')
        feed = feedparser.parse(self._feed_url)
        if feed.has_key('bozo_exception'):
            return 'Subscribe %s failed - %s' % (self._feed_url, feed['bozo_exception'].message)
        if self._feed_url not in self._subscripted.keys():
            self._subscripted[self._feed_url] = {'users':[self._user], 'etag':feed.etag}
        if self._user not in self._subscripted[self._feed_url]['users']:
            self._subscripted[self._feed_url]['users'].append(self._user)
            self._subscripted[self._feed_url]['etag'] = feed.etag

        content = ''
        for item in feed.entries:
            for c in item['content']:
                content += c['value']
        return 'Subscribe %s messages: %s' % (self._feed_url, content)

    def unsub(self):
        if not self._feed_url:
            return self.usage('unsub')
        if not self._subscripted.has_key(self._feed_url):
            return "Not Found: %s" % self._feed_url
        if self._user in self._subscripted[self._feed_url]['users']:
           self._subscripted[self._feed_url]['users'].remove(self._user)
        if not self._subscripted[self._feed_url]['users']:
            del self._subscripted[self._feed_url]

        return 'Unsubscribe %s completed' % self._feed_url

    def ls(self):
        subscripted = []
        for k,v in self._subscripted.iteritems():
            if self._user in v['users']:
                subscripted.append(k)
        if not subscripted:
            return "Subscribed is empty"
        return '\n'.join(subscripted)

    def pause(self):
        if not self._feed_url:
            return self.usage('pause')

        self.unsub()
        return 'Pause %s completed' % self._feed_url

    def resume(self):
        if not self._feed_url:
            return self.usage('resume')

        self.sub()
        return 'Resume %s completed' % self._feed_url

    def grep(self):
        if not (self._feed_url and self._keyword):
            return self.usage('grep')

        return 'TODO: grep %s %s' % (self._feed_url, ','.join(self._keyword)) 
        
    def usage(self, cmd):
        if cmd == 'grep':
            return "Usage: %s feed_url keyword" % cmd
        return "Usage: %s feed_url" % cmd

class CommandError(Exception):
    def __str__(self):
        return "Error - Unsupported command"
